package app.myproject.action.event;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import app.myproject.dao.EventDAOImpl;
import app.myproject.model.EventVO;
import app.myproject.util.CustomeKeyEditor;
import app.myproject.validator.EventValidator;


@Controller
@RequestMapping("/event")
@SessionAttributes(value={"event"})
public class EventController {

	@Resource 
	EventValidator validator;
	
	@Autowired
	public EventController(EventValidator eventValidator){
		this.validator = eventValidator;
	}
	
	@InitBinder
	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
	
	    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
	    dateFormat.setLenient(false);

	    binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));
	    binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
	    binder.registerCustomEditor(List.class, new CustomCollectionEditor(List.class));
	    binder.registerCustomEditor(com.google.appengine.api.datastore.Key.class, new CustomeKeyEditor());

	}
	
	protected boolean validate(EventVO event, BindingResult result) {
		validator.validate(event, result);
		if (result.hasErrors()) {
			printErrorLog(result);
			return false;
		}
		return true;
	}
	
	protected void printErrorLog(BindingResult result) {
		System.out.println("errors");
		for (ObjectError error:result.getAllErrors()) {
			System.out.println(error.getDefaultMessage());
		}
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public String forward(ModelMap model) {
		return "forward:list";
	}
	
	@RequestMapping(value = "/add", method = RequestMethod.GET)
	public String toAdd(ModelMap model) {
		System.out.println("toAdd");
		
		EventDAOImpl dao = new EventDAOImpl();
		EventVO event = dao.create();
		model.addAttribute("event",event);
		
		return "event/add";
	}

	@RequestMapping(value = "/add", method = RequestMethod.POST)
	public ModelAndView add(@ModelAttribute("event") EventVO event, BindingResult result, SessionStatus status) {
		System.out.println("add");
				
		if (validate(event, result)) {
			event.setDate(new Date());
			EventDAOImpl dao = new EventDAOImpl();
			dao.save(event);
			status.setComplete();			
		}
		else {
			return new ModelAndView("event/add");
		}
		
		return new ModelAndView("redirect:/event/list");
	}

	@RequestMapping(value = "/update/{encodedKey}", method = RequestMethod.GET)
	public String toEdit(@PathVariable String encodedKey, ModelMap model) {
		System.out.println("toEdit");
		
		EventDAOImpl dao = new EventDAOImpl();
		EventVO event = dao.find(encodedKey);
		model.addAttribute("event", event);
		
		return "event/update";

	}

	@RequestMapping(value = "/update/{encodedKey}", method = RequestMethod.POST)
	public ModelAndView edit(@PathVariable String encodedKey, @ModelAttribute("event") EventVO event, BindingResult result, SessionStatus status) {
		System.out.println("edit");
		
		if (validate(event, result)) {
			EventDAOImpl dao = new EventDAOImpl();
			dao.update(event);
			status.setComplete();
		} 
		else {
			return new ModelAndView("event/update");			
		}

		return new ModelAndView("redirect:/event/list");

	}

	@RequestMapping(value = "/delete/{encodedKey}", method = RequestMethod.GET)
	public ModelAndView delete(@PathVariable String encodedKey, ModelMap model) {
		System.out.println("delete");
		
		EventDAOImpl dao = new EventDAOImpl();
		dao.deleteById(encodedKey);

		return new ModelAndView("redirect:/event/list");

	}

	// get all events
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public String list(ModelMap model) {

		System.out.println("list");
		
		EventDAOImpl dao = new EventDAOImpl();
		List<EventVO> list = dao.list();	
		model.addAttribute("eventList", list);
		
		System.out.println("result: " + list.size());

		return "event/list";

	}

}